using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System;
using System.IO;

[assembly: CommandClass(typeof(InsertOlePicture))]

public class InsertOlePicture
{
    [CommandMethod("InsertOlePic")]
    public void InsertOlePic()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;

        try
        {
            Point3d insertionPoint = GetInsertionPoint(ed);
            if (insertionPoint == Point3d.Origin) return;

            string imagePath = GetImagePath(ed);
            if (string.IsNullOrEmpty(imagePath)) return;

            InsertOleObject(doc, insertionPoint, imagePath);
            ed.WriteMessage("\nOLE Picture inserted successfully.");
        }
        catch (Exception ex)
        {
            ed.WriteMessage($"\nError: {ex.Message}");
        }
    }

    private Point3d GetInsertionPoint(Editor ed)
    {
        PromptPointResult ppr = ed.GetPoint("Enter insertion point: ");
        if (ppr.Status != PromptStatus.OK) return Point3d.Origin;

        return ppr.Value;
    }

    private string GetImagePath(Editor ed)
    {
        PromptOpenFileOptions opts = new PromptOpenFileOptions("Select an image file")
        {
            Filter = "Image Files|*.bmp;*.jpg;*.jpeg;*.png;*.gif"
        };
        PromptFileNameResult pfnr = ed.GetFileNameForOpen(opts);
        if (pfnr.Status != PromptStatus.OK) return null;

        string imagePath = pfnr.StringResult;
        if (!File.Exists(imagePath))
        {
            ed.WriteMessage("\nFile not found.");
            return null;
        }

        return imagePath;
    }

    private void InsertOleObject(Document doc, Point3d insertionPoint, string imagePath)
    {
        using (Transaction tr = doc.TransactionManager.StartTransaction())
        {
            BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead);
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

            using (OleObject oleObj = new OleObject())
            {
                oleObj.ClassType = "AcOlePicture";
                oleObj.SourceFileName = imagePath;

                btr.AppendEntity(oleObj);
                tr.AddNewlyCreatedDBObject(oleObj, true);

                oleObj.TransformBy(Matrix3d.Displacement(insertionPoint.GetVectorTo(Point3d.Origin)));
                oleObj.ScaleFactors = new Scale3d(1.0, 1.0, 1.0);
            }

            tr.Commit();
        }
    }

    public void InsertOleImageFrame()
    {
        // Implementation for InsertOleImageFrame
    }
}
